package com.hxgis.common.service.impl;

import com.es.common.EsAggCondition;
import com.es.common.domain.EsCondition;
import com.es.common.domain.agg.Group;
import com.es.common.enums.Order;
import com.es.wrapper.DataWrapper;
import com.hxgis.common.dto.RainInfoAnalysDTO;
import com.hxgis.common.entity.ProcRainInfo;
import com.hxgis.common.enums.RainFlagEnum;
import com.hxgis.common.repository.ProcRainInfoRepository;
import com.hxgis.common.repository.RainDayInfoRepository;
import com.hxgis.common.service.ProcRainInfoService;
import com.hxgis.common.utils.TimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
public class ProcRainInfoServiceImpl implements ProcRainInfoService {

    @Autowired
    RainDayInfoRepository dayInfoRepository;

    @Autowired
    ProcRainInfoRepository procRainInfoRepository;

    @Override
    public List<RainInfoAnalysDTO> initProcRainInfo(String startTime, String endTime, String flag, Integer type) {

        EsAggCondition esAggCondition = EsAggCondition.getInstance();
        Group stationNoGroup = esAggCondition.Group("stationNo");
        stationNoGroup.size(10000);
        Group yearGroup = stationNoGroup.groupSub("year");
        yearGroup.size(30);
        Group courseGroup = null;
        if (Objects.equals(type,1)){
            if (Objects.equals(flag,"20")){
                courseGroup = yearGroup.groupSub("continueRainFll");
                courseGroup.count("continueRainFll","continueDay");
            }
            if (Objects.equals(flag,"08")){
                courseGroup = yearGroup.groupSub("continueRainFll08");
                courseGroup.count("continueRainFll08","continueDay");
            }
        }else{
            if (Objects.equals(flag,"20")){
                courseGroup = yearGroup.groupSub("notContinueRainFll");
                courseGroup.count("notContinueRainFll","continueDay");
            }
            if (Objects.equals(flag,"08")){
                courseGroup = yearGroup.groupSub("notContinueRainFll08");
                courseGroup.count("notContinueRainFll08","continueDay");
            }
        }

        courseGroup.min("time");
        courseGroup.sum(RainFlagEnum.getRainFlagEnum(flag).getMessage(),"rainFallSum");
        courseGroup.order(Order.DESC,"rainFallSum");
        //两天才算个过程 不可能超过 365/2
        courseGroup.size(200);
        EsCondition condition = esAggCondition.getCondition();
        if (Objects.equals(type,1)){
            if (Objects.equals(flag,"08")){
                condition.gte("time",startTime).lte(endTime)
                        .eq("continueRainFll08",null).not()
                        .lte(RainFlagEnum.getRainFlagEnum(flag).getMessage(),20000);
            }else if (Objects.equals(flag,"20")){
                condition.gte("time",startTime).lte(endTime)
                        .eq("continueRainFll",null).not()
                        .lte(RainFlagEnum.getRainFlagEnum(flag).getMessage(),20000);
            }
        }else{
            if (Objects.equals(flag,"08")){
                condition.gte("time",startTime).lte(endTime)
                        .eq("notContinueRainFll08",null).not()
                        .lte(RainFlagEnum.getRainFlagEnum(flag).getMessage(),20000);
            }else if (Objects.equals(flag,"20")){
                condition.gte("time",startTime).lte(endTime)
                        .eq("notContinueRainFll",null).not()
                        .lte(RainFlagEnum.getRainFlagEnum(flag).getMessage(),20000);
            }
        }

        List<RainInfoAnalysDTO> rainInfoAnalysDTO = dayInfoRepository.selectListAgg(esAggCondition, new DataWrapper<RainInfoAnalysDTO>() {
            @Override
            public RainInfoAnalysDTO wrapper(Map<String, Object> data) {
                RainInfoAnalysDTO rainInfoAnalysDTO = new RainInfoAnalysDTO();
                rainInfoAnalysDTO.setStationNo(data.get("stationNo").toString());
                if (Objects.equals(type,1)){
                    if (Objects.equals(flag,"20")){
                        rainInfoAnalysDTO.setCourseFlag(data.get("continueRainFll").toString());
                    }else if (Objects.equals(flag,"08")){
                        rainInfoAnalysDTO.setCourseFlag(data.get("continueRainFll08").toString());
                    }
                }else{
                    if (Objects.equals(flag,"20")){
                        rainInfoAnalysDTO.setCourseFlag(data.get("notContinueRainFll").toString());
                    }else if (Objects.equals(flag,"08")){
                        rainInfoAnalysDTO.setCourseFlag(data.get("notContinueRainFll08").toString());
                    }
                }
                rainInfoAnalysDTO.setYear(data.get("year").toString());
                rainInfoAnalysDTO.setTime(String.valueOf(new Double(data.get("time").toString()).intValue()));
                rainInfoAnalysDTO.setCountDays(Double.valueOf(data.get("continueDay").toString()));
                rainInfoAnalysDTO.setRainFallSum(Double.parseDouble(data.get("rainFallSum").toString()));
                return rainInfoAnalysDTO;
            }
        });

        return rainInfoAnalysDTO;

    }

    /**
     * 初始化降水过程 从原始表入降水过程表
     * @param startTime
     * @param endTime
     */
    @Override
    public void saveProRainInfoByTime(String startTime, String endTime) {
        List<RainInfoAnalysDTO> continueInfos20 = initProcRainInfo(startTime, endTime, "20", 1);
        List<ProcRainInfo> procContinue20s = new ArrayList<>();
        continueInfos20.stream().forEach(continue20 -> {
            ProcRainInfo procRainInfo = new ProcRainInfo();
            procRainInfo.setId(continue20.getStationNo() + continue20.getTime() + "20");
            procRainInfo.setStationNo(continue20.getStationNo());
            procRainInfo.setContinueDay_20(continue20.getCountDays().intValue());
            procRainInfo.setTotalRainFall_20(new Double(continue20.getRainFallSum()).intValue());
            procRainInfo.setYear(continue20.getYear());
            procRainInfo.setStartTime(Integer.parseInt(continue20.getTime()));
            //结束时间
            String endTimes = TimeUtil.nextDay(continue20.getTime(),continue20.getCountDays().intValue() - 1);
            procRainInfo.setEndTime(Integer.parseInt(endTimes));
            procRainInfo.setEndDays(endTimes.substring(4,8));
            procContinue20s.add(procRainInfo);
        });
        //保存20连续
        procRainInfoRepository.saveBatch(procContinue20s);


        List<RainInfoAnalysDTO> continueInfos08 = initProcRainInfo(startTime, endTime, "08", 1);
        List<ProcRainInfo> procContinue08s = new ArrayList<>();
        continueInfos08.stream().forEach(continue08 -> {
            ProcRainInfo procRainInfo08 = new ProcRainInfo();
            procRainInfo08.setId(continue08.getStationNo() + continue08.getTime() + "08");
            procRainInfo08.setStationNo(continue08.getStationNo());
            procRainInfo08.setContinueDay_08(continue08.getCountDays().intValue());
            procRainInfo08.setYear(continue08.getYear());
            procRainInfo08.setTotalRainFall_08(new Double(continue08.getRainFallSum()).intValue());
            procRainInfo08.setStartTime(Integer.parseInt(continue08.getTime()));
            //结束时间
            String endTimes = TimeUtil.nextDay(continue08.getTime(),continue08.getCountDays().intValue() - 1);
            procRainInfo08.setEndTime(Integer.parseInt(endTimes));
            procRainInfo08.setEndDays(endTimes.substring(4,8));
            procContinue08s.add(procRainInfo08);
        });
        //保存08连续
        procRainInfoRepository.saveBatch(procContinue08s);

        List<RainInfoAnalysDTO> notContinueInfos20 = initProcRainInfo(startTime, endTime, "20", 2);
        List<ProcRainInfo> procNotContinue20s = new ArrayList<>();
        notContinueInfos20.stream().forEach(notContinue20 -> {
            ProcRainInfo procNotRainInfo20 = new ProcRainInfo();
            procNotRainInfo20.setId(notContinue20.getStationNo() + notContinue20.getTime() + "20");
            procNotRainInfo20.setStationNo(notContinue20.getStationNo());
            procNotRainInfo20.setNotContinueDay_20(notContinue20.getCountDays().intValue());
            procNotRainInfo20.setYear(notContinue20.getYear());
            procNotRainInfo20.setStartTime(Integer.parseInt(notContinue20.getTime()));
            //结束时间
            String endTimes = TimeUtil.nextDay(notContinue20.getTime(),notContinue20.getCountDays().intValue() - 1);
            procNotRainInfo20.setEndTime(Integer.parseInt(endTimes));
            procNotRainInfo20.setEndDays(endTimes.substring(4,8));
            procNotContinue20s.add(procNotRainInfo20);
        });
        //保存08不连续
        procRainInfoRepository.saveBatch(procNotContinue20s);


        List<RainInfoAnalysDTO> notContinueInfos08 = initProcRainInfo(startTime, endTime, "08", 2);
        List<ProcRainInfo> procNotContinue08s = new ArrayList<>();
        notContinueInfos08.stream().forEach(notContinue08 -> {
            ProcRainInfo procNotRainInfo08 = new ProcRainInfo();
            procNotRainInfo08.setId(notContinue08.getStationNo() + notContinue08.getTime() + "08");
            procNotRainInfo08.setStationNo(notContinue08.getStationNo());
            procNotRainInfo08.setNotContinueDay_08(notContinue08.getCountDays().intValue());
            procNotRainInfo08.setYear(notContinue08.getYear());
            procNotRainInfo08.setStartTime(Integer.parseInt(notContinue08.getTime()));
            //结束时间
            String endTimes = TimeUtil.nextDay(notContinue08.getTime(),notContinue08.getCountDays().intValue() - 1);
            procNotRainInfo08.setEndTime(Integer.parseInt(endTimes));
            procNotRainInfo08.setEndDays(endTimes.substring(4,8));
            procNotContinue08s.add(procNotRainInfo08);
        });
        //保存08连续
        procRainInfoRepository.saveBatch(procNotContinue08s);

        log.info("保存{}到{}的过程数据",startTime,endTime);
    }

    @Override
    public void saveProRainInfoByYear(Integer startYear, Integer endYear) {

    }



}
